﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using YiSha.Util.Model;

namespace YiSha.SqlSugars
{
    /// <summary>
    /// 适配层接口
    /// </summary>
    public interface IAdapter
    {
        /// <summary>
        /// 新增
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool Insert<T>(T entity) where T : class, new();

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityList"></param>
        /// <returns></returns>
        bool Insert<T>(List<T> entityList) where T : class, new();

        /// <summary>
        /// 新增
        /// </summary>
        /// <typeparam name="T">新增实体</typeparam>
        /// <typeparam name="TResult">扩展实体</typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        object Insert<T, TResult>(TResult entity) where T : class, new();
        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="updateDic"></param>
        /// <returns></returns>
        bool Update<T>(T updateDic) where T : class, new();
        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="rowObj">rowObj为匿名对象时只更新指定列( 例如:new{ name='abc'}只更新name )，为T类型将更新整个实体(排除主键、自增列和禁止更新列)</param>
        /// <param name="filterExpression">过滤条件</param>
        /// <returns></returns>
        bool Update<T>(object rowObj, Expression<Func<T, bool>> filterExpression) where T : class, new();
        /// <summary>
        /// 修改指定的行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="rowObj"></param>
        /// <param name="columns">只更新指定列( 例如:db.Update<Student>(student,it => new{it.Name}))</param>
        /// <returns></returns>
        public bool UpdateColumns<T>(T rowObj, Expression<Func<T, object>> columns) where T : class, new();
        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="updateDic">更新字段</param>
        /// <param name="filterExpression">过滤条件</param>
        /// <returns></returns>
        bool Update<T>(T updateDic, Expression<Func<T, bool>> filterExpression) where T : class, new();
        /// <summary>
        ///  更新数据【排除指定的字段】
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="updateDic">更新字段</param>
        /// <param name="filterExpression">过滤条件</param>
        /// <returns></returns>
        bool UpdateIgnoreCol<T>(T updateDic, Expression<Func<T, object>> columns) where T : class, new();
        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="updateExpression">更新字段</param>
        /// <param name="filterExpression">过滤条件</param>
        /// <returns></returns>
        bool Update<T>(Expression<Func<T, T>> updateExpression, Expression<Func<T, bool>> filterExpression) where T : class, new();
        /// <summary>
        /// 删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filterExpression">过滤条件</param>
        /// <returns></returns>
        bool Delete<T>(Expression<Func<T, bool>> filterExpression) where T : class, new();

        /// <summary>
        /// 查询单个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where">Lamda 表达式</param>
        /// <returns></returns>
        T GetEntity<T>(Expression<Func<T, bool>> where) where T : class, new();

        /// <summary>
        /// 查询单个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where">Lamda 表达式</param>
        /// <param name="expression">查询字段</param>
        /// <returns></returns>
        T GetEntity<T>(Expression<Func<T, bool>> where, Expression<Func<T, T>> expression) where T : class, new();

        /// <summary>
        /// 根据主键值获取对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        T GetById<T>(object value) where T : class, new();

        /// <summary>
        /// 根据主键值获取对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="expression">查询字段</param>
        /// <returns></returns>
        T GetById<T>(object value, Expression<Func<T, T>> expression) where T : class, new();
        /// <summary>
        /// 查询对象集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">Lamda 表达式</param>
        /// <returns></returns>
        List<T> GetList<T>(Expression<Func<T, bool>> expression) where T : class, new();
        /// <summary>
        /// 查询对象集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        List<T> GetList<T>() where T : class, new();
        /// <summary>
        /// 查询对象集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where">Lamda 表达式</param>
        /// <param name="expression">查询字段</param>
        /// <returns></returns>
        List<T> GetList<T>(Expression<Func<T, bool>> where, Expression<Func<T, T>> expression) where T : class, new();
        /// <summary>
        /// 分页查询对象集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">条件表达式</param>
        /// <param name="pagination">分页信息</param>
        /// <returns></returns>
        Tuple<int, List<T>> GetPager<T>(Expression<Func<T, bool>> expression, Pagination pagination) where T : class, new();
        /// <summary>
        /// 判断是否存在
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">条件表达式</param>
        /// <returns></returns>
        bool Exists<T>(Expression<Func<T, bool>> expression) where T : class, new();

        /// <summary>
        /// 统计
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">条件表达式</param>
        /// <returns></returns>
        int Count<T>(Expression<Func<T, bool>> expression) where T : class, new();

        /// <summary>
        /// ADO数据查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql">执行语句</param>
        /// <param name="rowObj">条件表达式</param>
        /// <returns></returns>
        List<T> GetList<T>(string sql, object rowObj = null) where T : class, new();
        /// <summary>
        /// SQL分页查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql">SQL语句</param>
        /// <param name="rowObj">参数</param>
        /// <param name="pagination">分页信息</param>
        /// <returns></returns>
        Tuple<int, List<T>> GetPager<T>(string sql, Dictionary<string,object> pairs= null, Pagination pagination=null) where T : class, new();
        /// <summary>
        /// SQL分页查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql">SQL语句</param>
        /// <param name="pagination">分页信息</param>
        Tuple<int, List<T>> GetPager<T>(string sql, Pagination pagination = null) where T : class, new();
        /// <summary>
        /// 执行SQL返回受影响行数
        /// </summary>
        /// <param name="sql">执行语句</param>
        /// <param name="rowObj">条件表达式</param>
        /// <returns></returns>
        int ExecuteBySql(string sql, object rowObj = null);

        /// <summary>
        /// 带事务处理的执行数据库操作
        /// </summary>
        /// <param name="func">方法委托</param>
        /// <returns></returns>
        bool ExcuteTransaction(Func<SqlSugarClient, bool> func);

        /// <summary>
        /// 获取第一行第一列
        /// </summary>
        /// <param name="sql">执行语句</param>
        /// <param name="rowObj">条件表达式</param>
        /// <returns></returns>
        object GetScalar(string sql, object rowObj);
        #region SQL语句查询
        /// <summary>
        /// 查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="rowObj"></param>
        /// <returns></returns>
        List<T> SqlQuery<T>(string sql, object rowObj = null) where T : class, new();
        /// <summary>
        /// 获取第一行第一列
        /// </summary>
        /// <param name="sql">执行语句</param>
        /// <param name="rowObj">条件表达式</param>
        /// <returns></returns>
        int SqlQueryCount(string sql, object rowObj = null);
        #endregion
        /// <summary>
        /// 执行事务
        /// </summary>
        /// <typeparam name="Result"></typeparam>
        /// <param name="func"></param>
        /// <param name="commandTimeOut"></param>
        /// <returns></returns>
        Result ExecTran<Result>(Func<SqlSugarClient, Result> func, int commandTimeOut = 30);
    }
}